home *** CD-ROM | disk | FTP | other *** search
/ Programming Sound Cards / Programming Sound Cards.iso / sound_52 / ex1.ma < prev    next >
Text File  |  1995-01-01  |  7KB  |  387 lines

  1. #
  2. #
  3. # Illustrates idea of using continuous controllers to
  4. # implement pan between speakers 
  5. #
  6. # four vcos used.
  7. #
  8. # 2 for melody
  9. # 2 for pan control
  10. #
  11. # true setup
  12. #
  13. #    vco melody on channel n
  14. #    vco melody dupped on channel n+1
  15. #
  16. #    vco pan control 1
  17. #        volume messages to channel n
  18. #
  19. #    vco pan control 2
  20. #        volume messages to channel n+1
  21. #    
  22. # mos setup should map vco 4 to vco 2
  23. #               vco 3 to vco 1
  24. #
  25. # Mixer should have one vco to the left, one to the right.
  26. # Set pan to hard left and hard right appropriately.
  27. # Basic idea is that volume is continuously balanced by
  28. # ccont messages on left and right; i.e., strong on left
  29. # weak on right then move gradually to weak on left
  30. # strong on right; apparent voice position will shift.
  31. #
  32. # This takes an input argument from mos
  33. # e.g.,
  34. #
  35. # mos> set argv 3
  36. #
  37.  
  38. PORTAMENTO = 5
  39. VOLUME = 7
  40. PAN = 10
  41. SUSTAINPEDAL = 0x40
  42.  
  43. PANLEFT    = 127
  44. PANRIGHT = 30
  45.  
  46. TRUE    = 1
  47. FALSE    = 0
  48.  
  49. # pan control variables, one per channel
  50. #
  51. int vol1
  52. int vol2
  53.  
  54. # debug on/off
  55. int debug=TRUE
  56.  
  57. # minor scale offsets, jazz minor
  58. #
  59.  
  60. uchar minor[7]={
  61.     0,2,3,5,7,9,10
  62. }
  63.  
  64.  
  65. # major scale offsets, jazz major
  66. #
  67. uchar major[7]={
  68.     0,2,4,5,7,9,11
  69. }
  70.  
  71. # chord progression
  72. #
  73. uchar basis[9]={
  74.     E,LE,E,G,LG,B,LB,D,LD
  75. }
  76.  
  77. uchar notesPerRiff[9]={
  78.     6,12,6,12,12,6,3,9,12
  79. }
  80.  
  81. uchar riffsPerBasis[10]={
  82.     2,4,6,6,8,6,4,4,2,4
  83. }
  84.  
  85. int tottime
  86.  
  87. int panvalue
  88.  
  89. int octave=0
  90.  
  91. riff settime(beats,beatnote)
  92.     tottime = beats * beatnote
  93. end
  94.  
  95. riff nexttime()
  96. end
  97.  
  98. riff atoi(vector string)
  99.     int i
  100.     int n
  101.  
  102.     for( i = 0; ; )
  103.         if ( string[i] == ' ')
  104.             i++
  105.         else
  106.             break
  107.         end
  108.     end
  109.     for ( n = 0; string[i] >= '0' && string[i] <= '9'; i++)
  110.         n = 10 * n + string[i] - '0'
  111.     end
  112.  
  113.  
  114.     return(n)
  115. end
  116.  
  117. # move from current chord to next chord in progression
  118. #
  119. riff nextBasis(cur)
  120.     if ( cur == 9 )
  121.         return(0)
  122.     end
  123.     cur++
  124.     return(cur)
  125. end
  126.  
  127. # determine how many notes for this riff
  128. riff nextNotes(cur)
  129.     return(notesPerRiff[mrand()%9])
  130. end
  131.  
  132. # determine how many riffs for this chord
  133. #
  134. riff nextRiffs(cur)
  135.     return(riffsPerBasis[triangle(0,9)])
  136. end
  137.  
  138. LOSTRINGS = 4
  139. STRINGS = 5
  140. EGRAND = 8
  141.  
  142. int newport
  143. int newsustain
  144. int newpatch
  145. int disturbFlag = FALSE
  146. int resttime
  147. int restflag = FALSE
  148.  
  149. riff disturbMelodySetup()
  150.     int rno
  151.  
  152.     disturbFlag = TRUE
  153.     # must force a time switch, rest at end of chord
  154.     # change doesn't hurt either. time switch needed
  155.     # for 2nd voice to imitate
  156.     resttime = mchoose(q,e,q+e)
  157.     restflag = TRUE
  158.     rest    resttime
  159.  
  160.     rno = mchoose(0,1)
  161.  
  162.     if (rno)
  163.         newpatch =  mchoose(LOSTRINGS,STRINGS,EGRAND)
  164.         if (newpatch == LOSTRINGS)
  165.             octave = 12
  166.         else
  167.             octave = 0
  168.         end
  169.         patch newpatch
  170.         newport = mchoose(0,0,0,0,5,10,10,15)
  171.         ccont 0     PORTAMENTO    newport
  172.         newsustain = mchoose(0,127)
  173.         ccont 0  SUSTAINPEDAL    newsustain
  174.         if (debug)
  175.             void printf("newpatch %d\n",newpatch)
  176.             void printf("newport %d\n",newport)
  177.             void printf("newsustain %d\n",newsustain)
  178.         end
  179.     end
  180. end
  181.  
  182. riff disturbDoppelGanger()
  183.     rest resttime
  184.     disturbFlag = FALSE
  185.     patch newpatch
  186.     ccont 0 PORTAMENTO    newport
  187.     ccont 0  SUSTAINPEDAL    newsustain
  188. end
  189.  
  190. int rno
  191. int nnote
  192. int ntime
  193. int nvel
  194.  
  195. riff playIt(nn,nt,nv)
  196.  
  197.     rno = mchoose(0,1,2,3)
  198.     nnote = nn+octave
  199.     ntime = nt
  200.     nvel  = nv
  201.  
  202.     if ( rno == 0 )
  203.         nnote    nt    nv
  204.     else if ( rno == 1 )
  205.         nnote-12    0,nt    nv    
  206.         nnote    nt    nv
  207.     else if ( rno == 2 )
  208.         nnote-12    0,nt    nv
  209.         nnote-5    0,nt    nv
  210.         nnote    nt    nv
  211.     else if ( rno == 3 )
  212.         nnote     nt    nv
  213.     end
  214.  
  215. end
  216.  
  217. riff imitate()
  218.     if ( rno == 0 )
  219.         nnote        ntime    nvel
  220.     else if ( rno == 1 )
  221.         nnote-12    0,ntime        nvel    
  222.         nnote        ntime    nvel
  223.     else if ( rno == 2 )
  224.         nnote-12    0,ntime        nvel
  225.         nnote-5        0,ntime    nvel
  226.         nnote        ntime    nvel
  227.     else if ( rno == 3 )
  228.         nnote        ntime    nvel
  229.     end
  230. end
  231.  
  232. # @include pan1.ma
  233.  
  234. riff vco1sect1()
  235. end
  236.  
  237. riff vco2sect1()
  238. end
  239.  
  240. riff vco3sect1()
  241. end
  242.  
  243. riff vco4sect1()
  244. end
  245.  
  246. # melody
  247. vco melody
  248.     int curbasis         # current chord in progression
  249.     int curnotes        # number of notes in riff
  250.     int curriffs        # riffs per chord
  251.     int cr            # current riff index
  252.     int cn            # current note index
  253.     int rno            # random number variable
  254.     int scalemode        # major or minor mode index
  255.     int newnote
  256.     int newtime
  257.     int newvel
  258.  
  259.     # pass per ccont pan time in from mos argv
  260.     # environment pointer
  261.     #
  262.     panvalue = atoi(&argv)
  263.     if (panvalue == 0)
  264.         panvalue = 5
  265.     end
  266.     void printf("panvalue = %d\n",panvalue)
  267.  
  268.     void vco1sect1()
  269.  
  270.     # section two
  271.  
  272.  
  273.     # section three
  274.     scalemode = mrand() % 2
  275.     for( curbasis = 0; ; )
  276.  
  277.         curriffs = nextRiffs(0)
  278.  
  279.         #
  280.         # for some number of riffs
  281.         for( cr = 0; cr < curriffs; cr++)
  282.             # for each riff play some number of notes
  283.             #
  284.             curnotes = nextNotes(0)
  285.             newvel = mrandrange(90,100)
  286.             for( cn = 0; cn < curnotes; cn++)
  287.                 rno = mfractal1(rno) %  7
  288.                 if (scalemode)
  289.                     newnote =  basis[curbasis] + major[rno]
  290.                 else
  291.                     newnote =  basis[curbasis] + minor[rno]
  292.                 end
  293.                 newvel = newvel + 5
  294.                 if ( newvel > 120 )
  295.                     newvel = 89
  296.                 end
  297.                 newtime = mchoose(q,e,s,s,s,s,s,s,e,e,e,e,q+e) 
  298. #                 void printf("%d %d %d\n",newnote,newtime,newvel)
  299.                 void playIt(newnote,newtime,newvel)
  300.                 newnote newtime newvel
  301.             end
  302.             # sometimes throw in a rest
  303.             #
  304.             rno = mrand() % 3
  305.             if (rno)
  306.                 resttime = mchoose(q,e,e,h+q,e,q+e)
  307.                 rest resttime
  308.                 restflag = TRUE
  309.             end
  310.         end
  311.         curbasis = nextBasis(curbasis)
  312.         # flip coin to decide if major/minor mode
  313.         #
  314.         scalemode = mrand() % 2
  315.         void disturbMelodySetup()
  316.     end
  317. end
  318.  
  319. vco melodyDup
  320.  
  321.     void vco2sect1()
  322.  
  323.     # section three
  324.     for(;;)
  325.         #void printf("v2 restflag %d\n",restflag)
  326.         if (restflag)
  327.             restflag = FALSE
  328.             rest resttime
  329.         else
  330.             void imitate()
  331.         end
  332.         if (disturbFlag)
  333.             void disturbDoppelGanger()
  334.         end
  335.     end
  336. end
  337.  
  338.  
  339. vco pan1
  340.     int decflag
  341.     int mcount
  342.     int vol
  343.     int dirflag
  344.  
  345.     void vco3sect1()
  346.  
  347.     # force pan control to left channel, mixer must be setup to
  348.     # match
  349.     vol1 = PANLEFT
  350.     vol2 = PANRIGHT
  351.     for(;;)
  352.         if (vol1 >= PANLEFT)
  353.             void printf("PAN LEFT max %d %d\n",vol1,vol2)
  354.             decflag = TRUE
  355.         else if (vol1 <= PANRIGHT)
  356.             void printf("PAN LEFT min %d %d\n",vol1,vol2)
  357.             decflag = FALSE
  358.         end
  359.         if (decflag)
  360.             vol1--
  361.             vol2++
  362.         else
  363.             vol1++
  364.             vol2--
  365.         end
  366.         ccont    panvalue    VOLUME    vol1
  367.         #void printf("vol1 %d ",vol1)
  368.     end
  369. end
  370.  
  371. vco pan2
  372.     int mcount
  373.     int vol
  374.     int dirflag
  375.  
  376.     void vco4sect1()
  377.  
  378.     # force pan control to right channel, mixer must be setup to
  379.     # match
  380.     for(;;)
  381.         ccont    panvalue    VOLUME    vol2
  382.         #void printf("vol2 %d\n",vol2)
  383.     end
  384. end
  385.